# -*- coding:utf-8 -*-
from django.contrib.auth.models import User
from django.core.exceptions import PermissionDenied
from django.core.urlresolvers import reverse
from django.db.models.base import Model
from django.http import Http404
from django.http.response import HttpResponseForbidden, HttpResponse
from django.shortcuts import render_to_response, redirect
from django.template import RequestContext
from django.template.context import RequestContext
from django.template.defaultfilters import time
from django.utils import simplejson
from django.views.decorators.csrf import csrf_exempt
from django_countries.countries import COUNTRIES
from models import InformePais
from forms import InformePaisForm
from universidades.models import Universidad, Region, Pais_region
from universidades.views import sidebar
from validaciones.models import checkpermiso, respuestahttp
import datetime
import re


Permisos = ['validaciones.Participantes_Publico']

def get_pais_name( codigo_pais_parametro ):

    for code, name in COUNTRIES:
        if codigo_pais_parametro == code:
            return name
    return ''

def formulario( request, pais_informe_param = '' , pk_informe_param = 0 ):

    url = request.get_full_path()

    # obtener id de usuario para conocer si tiene permisos sobre esta operacion.
    # solo administrador regional puede crear, editar y eliminar informes de paises de su region.
    is_adm_regional = request.user.groups.filter( name = 'Adm. Regional' ).exists()
    is_adm_institucional = request.user.groups.filter( name = 'Adm. Institucional' ).exists()

    if not is_adm_regional:
        html = "<html><body><h1>Acceso denegado</h1><a href=\"/plataforma\"> Volver a la pagina de inicio</a></body></html>"
        return HttpResponse( html )


    # info marca si se despliega el formulario nuevo o un mensaje de guardado en caso de aplicar el submit
    info_enviado = 'Nuevo'
    pais_formulario_antiguo = ''
    pk_informe_antiguo = 0


    # Caso que haga el submit
    if request.method == 'POST':

        bandera_validacion, mensaje_error = validar_datos( request )
        print bandera_validacion
        if bandera_validacion:
            try:
                pais_formulario_antiguo = request.POST['pais_formulario_antiguo']
                pk_informe_antiguo = request.POST['pk_informe_antiguo']

                # Si es un formulario editado entonces trae el identificador de tal formulario
                formulario_creado = InformePais.objects.get( id = pk_informe_antiguo )
                formulario_creado.resumen = request.POST['resumen']
                formulario_creado.fecha_inicio , mensaje_error = obtenerFecha( request, 'inicio' )
                formulario_creado.fecha_fin  , mensaje_error = obtenerFecha( request, 'fin' )

                # Como se puede ver la variable pais no se altera, que cargue en el pais adecuado.
                if 'archivo' in request.FILES:
                    formulario_creado.archivo = request.FILES['archivo']

                formulario_creado.save()
                info_enviado = 'Editado'
                return redirect( '/plataforma/listar_informes_pais/' + "?message=El formulario fue editado con exito." )

            except InformePais.DoesNotExist:

                # Caso que el formulario sea nuevo
                formulario_creado = InformePaisForm( request.POST, request.FILES )
                if formulario_creado.is_valid():
                    formulario_creado.save( request.user, request.POST['pais_formulario_antiguo'] )
                    info_enviado = 'Guardado'
                    print "Nuevo informe cargado"
                else:
                    print formulario_creado.errors
            except Exception, e:
                raise e
        else:
            print "Ocurrio un error al procesar la el formulario"
            info_enviado = 'Error'
            pais_formulario_antiguo = request.POST['pais_formulario_antiguo']
            pk_informe_antiguo = request.POST['pk_informe_antiguo']
            nombre_pais = get_pais_name( pais_formulario_antiguo )
            formulario_creado = InformePaisForm( request.POST , request.FILES )
            if 'archivo' in request.FILES:
                formulario_creado.archivo = request.FILES['archivo']



    else:
        # Caso en que el formulario se este editando, carga datos antiguos
        if not pk_informe_param == 0:
            informe_anterior = InformePais.objects.get( pk = pk_informe_param )
            formulario_creado = InformePaisForm( instance = informe_anterior )
            pais_formulario_antiguo = pais_informe_param
            pk_informe_antiguo = pk_informe_param
            nombre_pais = get_pais_name( pais_formulario_antiguo )


        else:
            # Caso no existan datos sobre ese pais
            formulario_creado = InformePaisForm()
            # Bloquear la edicion de pais del informe
            pais_formulario_antiguo = pais_informe_param
            pk_informe_antiguo = 0
            nombre_pais = get_pais_name( pais_formulario_antiguo )

    menu = sidebar( request )

    return render_to_response( 'informes_pais_form.html', locals(), context_instance = RequestContext( request ) )


def ver_informes( request, pk_informe ):
    # pk_informe es el id del informe que se desea ver.
    if checkpermiso( request.user, Permisos ):
        return HttpResponse( respuestahttp() )

    try:
        informe = InformePais.objects.get( pk = pk_informe )
    except InformePais.DoesNotExist:
        raise Http404

    menu = sidebar( request )
    return render_to_response( 'ver_informe_pais.html', locals(), context_instance = RequestContext( request ) )

def listar_paises_segun_region( request ):


    if checkpermiso( request.user, Permisos ):
        return HttpResponse( respuestahttp() )

    if 'message' in request.GET:
        message = request.GET['message']

    # Revisar si es administrador regional
    is_adm_regional = request.user.groups.filter( name = 'Adm. Regional' ).exists()
    is_adm_institucional = request.user.groups.filter( name = 'Adm. Institucional' ).exists()

    # Si no es administrador regional, prohibirle acceso
    if not is_adm_regional:
        html = "<html><body><h1>Acceso denegado</h1><a href=\"/plataforma\"> Volver a la pagina de inicio</a></body></html>"
        return HttpResponse( html )

    # Obtener id de usuario que hace la peticion de ver los paises de una region dada
    # Traer todos los paises/universidades que existen de una determinada region
    region_administrada = Region.objects.get( administrador = request.user.pk )
    universidades = Universidad.objects.filter( region = region_administrada )


    # Crear lista de paises y apuntar el link a sus informes en caso de que existan
    # Si existe indicarle en la lista que (Posee informe - en fecha tal)
    # Si no existen enviarle a un formulario vacio donde cargar
    # Si no tiene indicarle que no tiene informe de pais

    lista_de_paises = []
    nombre_de_paises = []


    for universidad in universidades:
        lista_de_paises.append( universidad.pais )
        nombre_de_paises.append( universidad.pais.name )

    # Codigo y nombre de pais 'en el mismo orden' en dos lista
    lista_de_paises = eliminar_duplicados( lista_de_paises )
    nombre_de_paises = eliminar_duplicados( nombre_de_paises )

    # Indica si el pais tiene mas de un informe de manera a crear link a la pagina donde se puedan listar los otros.
    mas_de_un_informe = []
    informes_de_paises = []

    for pais_dado in lista_de_paises:
        try:
            informe_auxiliar = InformePais.objects.filter( pais = pais_dado ).order_by( '-fecha_fin' )
            informes_de_paises.append( informe_auxiliar[0] )

            if informe_auxiliar.count() > 1:
                mas_de_un_informe.append( True )
            else:
                mas_de_un_informe.append( False )

        except:
            informes_de_paises.append( '' )
            mas_de_un_informe.append( False )

    # Sincronizar ambas listas
    lista_sinc_paises = zip( lista_de_paises, nombre_de_paises, informes_de_paises , mas_de_un_informe )
    # print "Proceso lista"
    # print lista_sinc_paises

    menu = sidebar( request )
    return render_to_response( 'listar_paises.html', locals(), context_instance = RequestContext( request ) )

def ver_informes_pais_anteriores( request, pais_informe_param = '' ):

    if checkpermiso( request.user, Permisos ):
        return HttpResponse( respuestahttp() )

    menu = sidebar( request )

    informes_auxiliar = InformePais.objects.filter( pais = pais_informe_param ).order_by( '-fecha_fin' )
    informes_paises = []

    pais = informes_auxiliar[0].pais
    for informe in informes_auxiliar:
        informes_paises.append( informe )

    return render_to_response( 'ver_informes_pais_anteriores.html', locals(), context_instance = RequestContext( request ) )


# Elimina los paises que se duplican al momento de hacer la consulta
def eliminar_duplicados( lista ):
    resultado = []
    for elemento in lista:
        if elemento in resultado:
            continue
        resultado.append( elemento )
    return resultado

def vista_publica_informes_pais( request ):

    if checkpermiso( request.user, Permisos ):
        return HttpResponse( respuestahttp() )


    # Revisar si es administrador regional
    is_adm_regional = request.user.groups.filter( name = 'Adm. Regional' ).exists()
    is_adm_institucional = request.user.groups.filter( name = 'Adm. Institucional' ).exists()

    universidades = Universidad.objects.all()

    lista_de_paises = []
    nombre_de_paises = []
    bandera_de_paises = []

    for universidad in universidades:
        lista_de_paises.append( universidad.pais )
        nombre_de_paises.append( universidad.pais.name )
        bandera_de_paises.append( universidad.pais.flag )

    lista_de_paises = eliminar_duplicados( lista_de_paises )
    nombre_de_paises = eliminar_duplicados( nombre_de_paises )
    bandera_de_paises = eliminar_duplicados( bandera_de_paises )

    regiones_de_paises = []
    informes_de_paises = []
    mas_de_un_informe = []

    for pais_dado in lista_de_paises:
        try:
            region = Pais_region.objects.get( pais = pais_dado )
            regiones_de_paises.append( region.region.nombre )
            # print pais_dado, region.region.nombre
            informe_auxiliar = InformePais.objects.filter( pais = pais_dado ).order_by( '-fecha_fin' )
            informes_de_paises.append( informe_auxiliar[0].id )

            if informe_auxiliar.count() > 1:
                mas_de_un_informe.append( True )
            else:
                mas_de_un_informe.append( False )

        except:
            informes_de_paises.append( '0' )
            mas_de_un_informe.append( False )

    # Sincronizar ambas listas
    lista_sinc_paises = zip( lista_de_paises, nombre_de_paises, bandera_de_paises, informes_de_paises, mas_de_un_informe, regiones_de_paises )
    lista_sinc_paises = sorted( lista_sinc_paises, key = lambda x: x[5] )

    # print lista_sinc_paises
    # Agrupar por region
    bandera_inicializacion = False
    region_anterior = ''
    paises_de_la_region = []
    lista_nueva = []

    for codigo, nombre, bandera, informe_id, mas_de_uno , region in lista_sinc_paises:
        if region_anterior == region:
            paises_de_la_region.append( [codigo, nombre, bandera, informe_id, mas_de_uno] )
        else:
            if bandera_inicializacion == True:
                lista_nueva.append( [region_anterior, paises_de_la_region] )
            else:
                bandera_inicializacion = True

            region_anterior = region
            paises_de_la_region = []
            paises_de_la_region.append( [codigo, nombre, bandera, informe_id, mas_de_uno] )

    lista_nueva.append( [region_anterior, paises_de_la_region] )

    menu = sidebar( request )
    return render_to_response( 'vista_publica_informes_pais.html', locals(), context_instance = RequestContext( request ) )

def convertir_a_timestamp( fecha ):

    return datetime.datetime.strptime( fecha , '%d/%m/%Y' ).date()


def obtenerFecha( request, pedido ):
    if pedido == 'inicio':
        # Devuelve la fecha de inicio del informe
        if request.POST['fecha_inicio'] == '':
            return False, unicode( '<li>Verifique fecha de inicio del periodo</li>' )
        else:
            return convertir_a_timestamp( request.POST['fecha_inicio'] ) , ''
    if pedido == 'fin':
        # Devuelve la fecha de fin del informe
        if request.POST['fecha_fin'] == '':
            return False, unicode( '<li>Verifique fecha de fin del periodo</li>' )
        else:
            return convertir_a_timestamp( request.POST['fecha_fin'] ) , ''

def validar_periodo( request ):

    # Obtener informes anteriores.
    universidad_en_cuestion = Universidad.objects.filter( administrador_id = request.user.id )
    informes_anteriores = InformePais.objects.filter( pais = request.POST['pais_formulario_antiguo'] ).order_by( '-fecha_fin' )

    periodo_esta_correcto = True
    mensaje = ''


    # Obtener la fecha de inicio cargada en el formulario
    fecha_inicio_tmp , mensaje_error = obtenerFecha( request, 'inicio' )
    if not fecha_inicio_tmp:
        mensaje += mensaje_error


    # 1era Validadcion, si las fechas estan cargadas y tienen el formato correcto
    # Obtener la fecha de fin cargada en el formulario
    fecha_fin_tmp , mensaje_error = obtenerFecha( request, 'fin' )
    if not fecha_fin_tmp:
        mensaje += mensaje_error

    # En caso que una de las fechas sean incorrecta, retornar el mensaje para que sea alterada.
    if not fecha_fin_tmp or not fecha_inicio_tmp:
        return False , mensaje



    # 2da validacion, si la fecha de fin es posterior a la fecha de inicio
    if fecha_fin_tmp < fecha_inicio_tmp:
        periodo_esta_correcto = False
        mensaje = '<li>Verifique el periodo, la fecha de inicio es posterior a la fecha de fin</li>'
    else:
        # 3era validacion, Si es la misma fecha de un informe anterior, validarlo.
        nro_formulario = request.POST['pk_informe_antiguo']
        informe_editado = InformePais.objects.filter( id = nro_formulario )

        if informe_editado.count() > 0:
            # Si el periodo de un formulario editado es el mismo entonces es valido
            if fecha_fin_tmp.strftime( "%d-%m-%Y" ) == informe_editado[0].fecha_fin.strftime( "%d-%m-%Y" ) and fecha_inicio_tmp.strftime( "%d-%m-%Y" ) == informe_editado[0].fecha_inicio.strftime( "%d-%m-%Y" ):
                periodo_esta_correcto = True
                mensaje = ''
            else:
                # Caso que el periodo no sea el mismo, verificar solapamiento con otro periodo que no sea el del mismo informe.
                for informe in informes_anteriores:
                    if not unicode( informe.id ) == nro_formulario:
                        if fecha_inicio_tmp < informe.fecha_fin and fecha_inicio_tmp > informe.fecha_inicio:
                            periodo_esta_correcto = False
                            break
                        if fecha_fin_tmp > informe.fecha_inicio and fecha_fin_tmp < informe.fecha_fin:
                            periodo_esta_correcto = False
                            break
        else:
            # Caso que el formulario sea nuevo, verificar que no haya solapamiento con otros informes.
            for informe in informes_anteriores:
                if fecha_inicio_tmp <= informe.fecha_fin and fecha_inicio_tmp >= informe.fecha_inicio:
                    periodo_esta_correcto = False
                    break
                if fecha_fin_tmp >= informe.fecha_inicio and fecha_fin_tmp <= informe.fecha_fin:
                    periodo_esta_correcto = False
                    break
                if fecha_inicio_tmp <= informe.fecha_inicio and fecha_fin_tmp >= informe.fecha_fin:
                    periodo_esta_correcto = False
                    break

        if periodo_esta_correcto:
            # Periodo correcto, puede validarse
            mensaje = 'Periodo válido'
        else:
            mensaje = unicode( '<li>Existe un solapamiento de periodo de informes. El periodo: ' + fecha_inicio_tmp.strftime( "%d-%m-%Y" ) + ' a ' + fecha_fin_tmp.strftime( "%d-%m-%Y" ) + ' se superpone a un informe anterior de: ' + informe.fecha_inicio.strftime( "%d-%m-%Y" ) + ' a ' + informe.fecha_fin.strftime( "%d-%m-%Y" ) + '</li>' )

    return periodo_esta_correcto, mensaje

def validar_datos( request ):

    extensiones_permitidas = ['pdf', 'doc', 'docx']
    datos_correctos = True
    mensaje = ''

    periodo_correcto, mensaje = validar_periodo( request )
    if not periodo_correcto:
        datos_correctos = False

     # Verificar resumen
    if request.POST['resumen'] == '':
       datos_correctos = False
       mensaje += unicode( '<li>Favor complete el campo resumen</li>' ).encode( 'utf-8' )

    if not 'archivo' in request.FILES:
        if request.POST['pk_informe_antiguo'] == 0:
            datos_correctos = False
            mensaje += unicode( '<li>No ha ingresado ningun archivo/documento</li>' ).encode( 'utf-8' )
    else:
        nombre_archivo = request.FILES['archivo'].name
        nombre_archivo = nombre_archivo.split( '.' )
        # print nombre_archivo[-1]
        if not nombre_archivo[-1] in extensiones_permitidas:
            datos_correctos = False
            mensaje += unicode( '<li>Formato de archivo/documento no valido. Solo se permiten las extensiones pdf, doc y docx.</li>' ).encode( ' utf-8' )

    return datos_correctos, mensaje

@csrf_exempt
def ajax_control_periodo( request ):
    # Verificar si es una peticion ajax
    if request.is_ajax() and request.method == 'POST':
        bandera, mensaje = validar_periodo( request )
        mensaje = re.sub( '<[^<]+?>', '', mensaje )
        respuesta = {'bandera':bandera, "mensaje":mensaje}
        return HttpResponse( simplejson.dumps( respuesta ), mimetype = 'application/json' )



